package leafedbox.utils
{
	/**
	 * This class provides utility functions for doing standard set-based operations.
	 */
	public class ArrayUtil
	{
		/**
		 * Accepts two arrays and returns an array of items that occur in both sets.
		 * 
		 * @param a  An array.
		 * @param b  An array.
		 * 
		 * @returns An array of items that occur in both input arrays.
		 */
		public static function intersect(a:Array, b:Array):Array
		{
			var i:int, j:int;
			var ret : Array = new Array();
			
			// Cache array length for performance
			var len1 : uint = a.length;
			var len2 : uint = b.length;
			
			for(i=0; i<len1; i++) {
				for(j=0; j<len2; j++) {
					if(a[i] == b[j]) {
						ret.push(a[i]);
					}
				}
			}
			
			// Remove any duplicates
			dedup(ret);
			
			// Return new array
			return ret;
		}


		/**
		 * Accepts two arrays and returns the first array, minus the items in the second array.
		 * 
		 * @param a  An array.
		 * @param b  An array.
		 * 
		 * @returns A copy of the first array minus the items in the second array.
		 */
		public static function minus(a:Array, b:Array):Array
		{
			var i:int, j:int;
			var ret : Array = new Array();
			
			// Cache array length for performance
			var len1 : uint = a.length;
			var len2 : uint = b.length;
			
			for(i=0; i<len1; i++) {
				var flag : Boolean = false;
				
				// Check if it exists in the second array
				for(j=0; j<len2; j++) {
					if(a[i] == b[j]) {
						flag = true;
					}
				}
				
				// Add it to new array if it doesn't exist
				if(!flag) {
					ret.push(a[i]);
				}
			}
			
			// Return new array
			return ret;
		}


		/**
		 * Combines two arrays into a single, non-duplicated array
		 * 
		 * @param a  An array.
		 * @param b  An array.
		 * 
		 * @returns An array containing all the items from both input arrays.
		 */
		public static function union(a:Array, b:Array):Array
		{
			var i:int, j:int;
			var ret : Array = a.slice();
			
			// Remove duplicates
			dedup(ret);
			
			// Cache array length for performance
			var len1 : uint = a.length;
			var len2 : uint = b.length;
			var len3 : uint = ret.length;
			
			// Add items from second array if they don't exist.
			for(i=0; i<len2; i++) {
				var flag : Boolean = false;
				
				// Check if it exists in the new array
				for(j=0; j<len3; j++) {
					if(b[i] == ret[j]) {
						flag = true;
						break;
					}
				}
				
				// Add it to new array if it doesn't exist
				if(!flag) {
					ret.push(b[i]);
				}
			}
			
			// Return new array
			return ret;
		}


		/**
		 * Removes all duplicates from an array.
		 * 
		 * @param arr  An array.
		 */
		public static function dedup(arr:Array):void
		{
			var i:int, j:int;
			
			// Remove any duplicates
			var len:uint = arr.length;
			if(len > 1) {
				for(i=0; i<len-1; i++) {
					for(j=i+1; j<len; j++) {
						if(arr[i] == arr[j]) {
							arr.splice(j--, 1);
							len--;
						}
					}
				}
			}
		}

	}
}